<script setup lang="ts">
/**
 * @/views/culture/MerchantPage.vue
 * 描述 MerchantPage 页面
 */
/**
 * 商店管理页面
 */

/* 引入 */
import { ref, reactive, inject, onMounted, watch } from "vue";
import { ElMessage } from "element-plus";
import COS from "cos-js-sdk-v5";
import { config } from "../../../config.js";
import { useUserStore } from "@/stores/index.js";

/* 数据 */
const axios = inject("$axios");
const merchants = ref([]);
const erweimapicFile = ref([]);
const pictureurlFile = ref([]);
const addDialogVisible = ref(false);
const editDialogVisible = ref(false);
const dialogVisible = ref(true);
const userStore = useUserStore();
const currentUserRole = ref(userStore.currentUser.role);

// 配置 cos 全局对象
const cos = new COS({
  SecretId: config.secret_id,
  SecretKey: config.secret_key,
});
// 添加表单数据
const form = reactive({
  merchantname: "",
  sort: "",
  info: "",
  town: "",
  erweimapic: "",
  pictureurl: "",
});
// 修改表单数据
const editForm = reactive({
  merchantname: "",
  updateData: {
    info: "",
    merchantname: "",
    sort: "",
    town: "",
  },
});
// 表单上传次数(上传多个图片时进行一次计数)
const uploadCount = ref(0);

/* 钩子 */
onMounted(() => {
  // 发送请求获取商店列表
  axios
    .get("/merchants/list")
    .then((res) => {
      merchants.value = res.data;
    })
    .catch((err) => {
      console.error("获取商家列表失败:", err);
    });
});

/* 回调 */
// 修改商家回调
const editmerchant = (merchant) => {
  editForm.merchantname = merchant.merchantname;

  // 自动获取商店信息填入修改表单
  editForm.updateData.merchantname = merchant.merchantname;
  editForm.updateData.info = merchant.info;
  editForm.updateData.sort = merchant.sort;
  editForm.updateData.town = merchant.town;

  // 显示弹窗
  editDialogVisible.value = true;
};

// 删除商店回调
const deletemerchant = (merchant) => {
  axios
    .delete("/merchants", {
      data: {
        merchantname: merchant.merchantname,
      },
    })
    .then(() => {
      merchants.value = merchants.value.filter((t) => t._id !== merchant._id); // 更新前端商店列表(这句很好, 可以不用发起请求)
      ElMessage({
        message: `已删除商店：${merchant.merchantname}`,
        type: "success",
      });
    })
    .catch((err) => {
      console.error("删除商店失败:", err);

      ElMessage({
        message: "删除商店失败，请稍后再试！",
        type: "error",
      });
    });
};

// 添加商店回调
const addmerchant = () => {
  // 清空添加表单数据, 避免后续干扰
  form.merchantname = "";
  form.sort = "";
  form.info = "";
  form.town = "";
  form.erweimapic = "";
  form.pictureurl = "";

  erweimapicFile.value = "";
  pictureurlFile.value = "";

  // 显示弹窗
  addDialogVisible.value = true;
};

// 通过审核回调
const pushMerchant = (merchants) => {
  axios
    .put("/merchants/publish-status", {
      merchantname: merchants.merchantname,
      isPublished: !merchants.isPublished,
    })
    .then(() => {
      merchants.isPublished = !merchants.isPublished;
      if (merchants.isPublished) {
        ElMessage({
          message: `${merchants.merchantname} 已通过审核`,
          type: "success",
        });
      } else {
        ElMessage({
          message: `${merchants.merchantname} 已取消审核`,
          type: "success",
        });
      }
    })
    .catch((err) => {
      console.error("通过审核失败:", err);

      ElMessage({
        message: "通过审核失败, 请稍后再试！",
        type: "error",
      });
    });
};

// 提交添加商店表单回调
const submitAddmerchantForm = () => {
  // 校验表单数据
  if (
    !form.merchantname ||
    !form.sort ||
    !form.info ||
    !form.town ||
    !form.erweimapic ||
    !form.pictureurl
  ) {
    ElMessage({
      message: "请填写完整的商店信息!",
      type: "error",
    });
    return;
  }

  // 提交表单数据
  axios
    .post("/merchants", {
      merchantname: form.merchantname,
      sort: form.sort,
      info: form.info,
      town: form.town,
      erweimapic: form.erweimapic,
      pictureurl: form.pictureurl,
    })
    .then((res) => {
      ElMessage({
        message: `已添加商店: ${res.data.merchantname}`,
        type: "success",
      });

      merchants.value.push(res.data); // 更新商店列表(也是一种无需发起请求的更新方式)
    })
    .catch((err) => {
      console.error("添加商店失败:", err);
      ElMessage({
        message: "添加商店失败, 请检查输入信息!",
        type: "error",
      });
      addDialogVisible.value = false; // 关闭弹窗
    });

  addDialogVisible.value = false; // 关闭弹窗
  dialogVisible.value = false; // TODO: 这是关闭另外一个弹窗用的, 有些潦草, 不过逻辑正确
};

// 提交修改商店表单回调
const submitEditmerchantForm = () => {
  // TODO: 校验表单数据

  // 提交更新请求
  axios
    .put("/merchants", {
      merchantname: editForm.merchantname,
      updateData: editForm.updateData,
    })
    .then((res) => {
      // 更新列表
      const updatedMerchant = res.data.updatedMerchant; // 获取更新后的完整商家数据

      const index = merchants.value.findIndex(
        (merchant) => merchant._id === updatedMerchant._id, // 找到并更新商店列表中的对应商店
      );

      if (index !== -1) {
        merchants.value[index] = updatedMerchant; // 使用更新后的商店数据替换对应商家
      }

      // 成功提示
      ElMessage({
        message: `商家信息修改成功！`,
        type: "success",
      });
      editDialogVisible.value = false; // 关闭对话框
    })
    .catch((err) => {
      // 错误提示
      console.log(err);
      ElMessage({
        message: "修改商家失败, 请稍后重试!",
        type: "error",
      });
    });
};

// 上传图片到 COS 并获取 URL 回调(多少个文件就调用多少次)
const uploadToCos_erweimapic = async (file) => {
  const suffix = file.file.name.split(".").pop(); // 获取文件后缀名
  const key = `${config.town_of_bucket}/${Date.now()}-${Math.random()}.${suffix}`; // 生成文件存储路径
  const index = uploadCount.value; // 获取递归次数
  const data = erweimapicFile.value[index].raw; // 获取文件内容

  // 设置上传参数
  const params = {
    Bucket: config.bucket,
    Region: config.region,
    Key: key,
    Body: data, // 文件内容 (必须是 raw 属性的值)
    ContentType: file.type, // 文件类型
  };

  // 如果一个组件上传完毕就重置计数
  uploadCount.value = 0;

  // 尝试返回 url 路径
  try {
    // 返回一个 Promise 来确保文件上传成功后才返回结果
    await new Promise((resolve, reject) => {
      cos.putObject(params, (err) => {
        if (err) {
          // 如果上传失败，抛出错误
          reject("存储失败!");
        } else {
          // 上传成功
          resolve(
            `https://${params.Bucket}.cos.${params.Region}.myqcloud.com/${params.Key}`,
          );
        }
      });
    });

    // 提供用户提醒(每个文件提醒一次)
    ElMessage({
      message: "文件成功上传到云端",
      type: "success",
    });

    // 上传成功，返回文件的 URL
    const fileUrl = `https://${params.Bucket}.cos.${params.Region}.myqcloud.com/${params.Key}`;
    return fileUrl;
  } catch (error) {
    // 如果上传失败，提示错误信息
    ElMessage({
      message: "文件无法上传到云端",
      type: "error",
    });
    throw new Error(error); // 重新抛出错误
  }
};
// 添加图片文件上传回调(多少个文件就调用多少次)
const handleFileUpload_erweimapic = async (file: File) => {
  try {
    const fileUrl = await uploadToCos_erweimapic(file); // 上传文件并获取链接
    form.erweimapic = fileUrl; // 将上传的文件 URL 添加到表单中
  } catch (err) {
    ElMessage({
      message: "URL 添加错误",
      type: "error",
    });
  }
};

// 上传图片到 COS 并获取 URL 回调(多少个文件就调用多少次)
const uploadToCos_pictureurl = async (file) => {
  const suffix = file.file.name.split(".").pop(); // 获取文件后缀名
  const key = `${config.town_of_bucket}/${Date.now()}-${Math.random()}.${suffix}`; // 生成文件存储路径
  const index = uploadCount.value; // 获取递归次数
  const data = pictureurlFile.value[index].raw; // 获取文件内容

  // 设置上传参数
  const params = {
    Bucket: config.bucket,
    Region: config.region,
    Key: key,
    Body: data, // 文件内容 (必须是 raw 属性的值)
    ContentType: file.type, // 文件类型
  };

  // 如果一个组件上传完毕就重置计数
  uploadCount.value = 0;

  // 尝试返回 url 路径
  try {
    // 返回一个 Promise 来确保文件上传成功后才返回结果
    await new Promise((resolve, reject) => {
      cos.putObject(params, (err) => {
        if (err) {
          // 如果上传失败，抛出错误
          reject("存储失败!");
        } else {
          // 上传成功
          resolve(
            `https://${params.Bucket}.cos.${params.Region}.myqcloud.com/${params.Key}`,
          );
        }
      });
    });

    // 提供用户提醒(每个文件提醒一次)
    ElMessage({
      message: "文件成功上传到云端",
      type: "success",
    });

    // 上传成功，返回文件的 URL
    const fileUrl = `https://${params.Bucket}.cos.${params.Region}.myqcloud.com/${params.Key}`;
    return fileUrl;
  } catch (error) {
    // 如果上传失败，提示错误信息
    ElMessage({
      message: "文件无法上传到云端",
      type: "error",
    });
    throw new Error(error); // 重新抛出错误
  }
};
// 添加图片文件上传回调(多少个文件就调用多少次)
const handleFileUpload_pictureurl = async (file: File) => {
  try {
    const fileUrl = await uploadToCos_pictureurl(file); // 上传文件并获取链接
    form.pictureurl = fileUrl; // 将上传的文件 URL 添加到表单中
  } catch (err) {
    ElMessage({
      message: "URL 添加错误",
      type: "error",
    });
  }
};

/* 侦听 */
watch(
  // 指定侦听的目标
  () => userStore.currentUser,
  // 发生改变时回调
  (newUser) => {
    if (newUser && newUser.username) {
      currentUserRole.value = newUser.role;
    }
  },
  { immediate: true }, // 这里的 immediate: true 确保在初次加载时也能触发
);
</script>

<template>
  <!-- 管理员视图 -->
  <div v-if="currentUserRole === 'admin'" class="merchant-page-admin">
    <el-card class="page-card">
      <template #header>
        <h2>管理员-商家管理</h2>
      </template>
      <!-- 添加表单组件 -->
      <div class="add-form-dialog">
        <el-dialog v-model="addDialogVisible" title="添加商家" width="500">
          <el-form :model="form">
            <!-- 商家名称 -->
            <el-form-item label="名称">
              <el-input
                v-model="form.merchantname"
                placeholder="请输入商家名称"
              />
            </el-form-item>
            <!-- 商家类别 -->
            <el-form-item label="类别">
              <el-select v-model="form.sort" placeholder="请选择商家类别">
                <el-option label="美食" value="美食" />
                <el-option label="商品" value="商品" />
                <el-option label="客栈" value="客栈" />
              </el-select>
            </el-form-item>
            <!-- 商家简介 -->
            <el-form-item label="简介">
              <el-input v-model="form.info" placeholder="请输入商家简介" />
            </el-form-item>
            <!-- 商家小镇 -->
            <el-form-item label="小镇">
              <!-- TODO: 可以网络请求获取小镇列表下拉菜单(并且要使用 id 后获取, 否则会出现小镇改名后无法同步修改别的小镇的问题...) -->
              <el-input v-model="form.town" placeholder="请输入商家所属小镇" />
            </el-form-item>
            <!-- 商家二维码 -->
            <el-form-item label="商家二维码">
              <!-- 属性解释: -->
              <!-- v-model:file-list="" 绑定用户选择的文件列表(由浏览器的 Blob URL 自动生成, 以实现预览功能, 并且可以找到文件的内容) -->
              <!-- list-type="" 图片上传后缩略展示方式 -->
              <!-- accept="" 允许的图片上传类型 -->
              <el-upload
                :multiple="false"
                v-model:file-list="erweimapicFile"
                :http-request="handleFileUpload_erweimapic"
                list-type="picture"
                accept="image/jpeg,image/png"
              >
                <!-- TODO: 禁止多次单选 -->
                <template #tip>
                  <!-- TODO: 文件大小做限制 -->
                  <div class="el-upload__tip">
                    <el-text class="mx-1" type="info">
                      仅允许上传一张 500kb .jpg/.png 格式图片
                    </el-text>
                  </div>
                </template>
                <el-button type="success">选择图片</el-button>
              </el-upload>
            </el-form-item>
            <!-- 商家图片 -->
            <el-form-item label="商家图片">
              <!-- 属性解释: -->
              <!-- v-model:file-list="" 绑定用户选择的文件列表(由浏览器的 Blob URL 自动生成, 以实现预览功能, 并且可以找到文件的内容) -->
              <!-- list-type="" 图片上传后缩略展示方式 -->
              <!-- accept="" 允许的图片上传类型 -->
              <el-upload
                :multiple="false"
                v-model:file-list="pictureurlFile"
                :http-request="handleFileUpload_pictureurl"
                list-type="picture"
                accept="image/jpeg,image/png"
              >
                <!-- TODO: 禁止多次单选 -->
                <template #tip>
                  <!-- TODO: 文件大小做限制 -->
                  <div class="el-upload__tip">
                    <el-text class="mx-1" type="info">
                      仅允许上传一张 500kb .jpg/.png 格式图片
                    </el-text>
                  </div>
                </template>
                <el-button type="success">选择图片</el-button>
              </el-upload>
            </el-form-item>
          </el-form>
          <template #footer>
            <div class="dialog-footer">
              <el-button @click="addDialogVisible = false">取消</el-button>
              <el-button type="primary" @click="submitAddmerchantForm"
                >添加
              </el-button>
            </div>
          </template>
        </el-dialog>
      </div>
      <!-- 修改表单组件 -->
      <div class="edit-form-dialog">
        <el-dialog v-model="editDialogVisible" title="修改商家" width="500">
          <el-form :model="editForm">
            <!-- 修改名称 -->
            <el-form-item label="商家名称">
              <el-input
                v-model="editForm.updateData.merchantname"
                placeholder="请输入商家名称"
              />
            </el-form-item>
            <!-- 修改简介 -->
            <el-form-item label="商家简介">
              <el-input
                v-model="editForm.updateData.info"
                placeholder="请输入商家简介"
              />
            </el-form-item>
            <!-- 修改所属 -->
            <el-form-item label="商家所属">
              <el-input
                v-model="editForm.updateData.town"
                placeholder="请输入商家所属"
              />
            </el-form-item>
            <!-- 修改类别 -->
            <el-form-item label="类别">
              <el-select
                v-model="editForm.updateData.sort"
                placeholder="请选择商家类别"
              >
                <el-option label="美食" value="美食" />
                <el-option label="商品" value="商品" />
                <el-option label="客栈" value="客栈" />
              </el-select>
            </el-form-item>
          </el-form>
          <template #footer>
            <div class="dialog-footer">
              <el-button @click="editDialogVisible = false">取消</el-button>
              <el-button type="primary" @click="submitEditmerchantForm">
                修改
              </el-button>
            </div>
          </template>
        </el-dialog>
      </div>
      <!-- 页面标题组件 -->
      <div class="header">
        <h3>商家列表</h3>
        <el-button type="primary" @click="addmerchant">添加商家</el-button>
      </div>
      <!-- 商店列表组件 -->
      <div class="table">
        <el-table :data="merchants" style="width: 100%" border stripe>
          <el-table-column prop="town" label="所属小镇" />
          <el-table-column prop="merchantname" label="商家名称" />
          <el-table-column prop="sort" label="商家类别" />
          <el-table-column label="商家操作">
            <template #default="{ row }">
              <el-space wrap :size="10">
                <el-button
                  type="primary"
                  size="small"
                  @click="editmerchant(row)"
                >
                  修改
                </el-button>
                <el-button
                  type="danger"
                  size="small"
                  @click="deletemerchant(row)"
                >
                  删除
                </el-button>
                <el-button
                  type="warning"
                  size="small"
                  :plain="!row.isPublished"
                  @click="pushMerchant(row)"
                >
                  {{ row.isPublished ? "通过审核" : "尚未审核" }}
                </el-button>
              </el-space>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-card>
  </div>
  <!-- 商家视图 -->
  <div v-if="currentUserRole === 'merchant'" class="merchant-page-merchant">
    <!-- 添加表单组件 -->
    <div class="add-form-dialog">
      <el-dialog v-model="dialogVisible" title="添加商家" width="500">
        <el-form :model="form">
          <!-- 商家名称 -->
          <el-form-item label="名称">
            <el-input
              v-model="form.merchantname"
              placeholder="请输入商家名称"
            />
          </el-form-item>
          <!-- 商家类别 -->
          <el-form-item label="类别">
            <el-select v-model="form.sort" placeholder="请选择商家类别">
              <el-option label="美食" value="美食" />
              <el-option label="商品" value="商品" />
              <el-option label="客栈" value="客栈" />
            </el-select>
          </el-form-item>
          <!-- 商家简介 -->
          <el-form-item label="简介">
            <el-input v-model="form.info" placeholder="请输入商家简介" />
          </el-form-item>
          <!-- 商家小镇 -->
          <el-form-item label="小镇">
            <!-- TODO: 可以网络请求获取小镇列表下拉菜单(并且要使用 id 后获取, 否则会出现小镇改名后无法同步修改别的小镇的问题...) -->
            <el-input v-model="form.town" placeholder="请输入商家所属小镇" />
          </el-form-item>
          <!-- 商家二维码 -->
          <el-form-item label="商家二维码">
            <!-- 属性解释: -->
            <!-- v-model:file-list="" 绑定用户选择的文件列表(由浏览器的 Blob URL 自动生成, 以实现预览功能, 并且可以找到文件的内容) -->
            <!-- list-type="" 图片上传后缩略展示方式 -->
            <!-- accept="" 允许的图片上传类型 -->
            <el-upload
              :multiple="false"
              v-model:file-list="erweimapicFile"
              :http-request="handleFileUpload_erweimapic"
              list-type="picture"
              accept="image/jpeg,image/png"
            >
              <!-- TODO: 禁止多次单选 -->
              <template #tip>
                <!-- TODO: 文件大小做限制 -->
                <div class="el-upload__tip">
                  <el-text class="mx-1" type="info">
                    仅允许上传一张 500kb .jpg/.png 格式图片
                  </el-text>
                </div>
              </template>
              <el-button type="success">选择图片</el-button>
            </el-upload>
          </el-form-item>
          <!-- 商家图片 -->
          <el-form-item label="商家图片">
            <!-- 属性解释: -->
            <!-- v-model:file-list="" 绑定用户选择的文件列表(由浏览器的 Blob URL 自动生成, 以实现预览功能, 并且可以找到文件的内容) -->
            <!-- list-type="" 图片上传后缩略展示方式 -->
            <!-- accept="" 允许的图片上传类型 -->
            <el-upload
              :multiple="false"
              v-model:file-list="pictureurlFile"
              :http-request="handleFileUpload_pictureurl"
              list-type="picture"
              accept="image/jpeg,image/png"
            >
              <!-- TODO: 禁止多次单选 -->
              <template #tip>
                <!-- TODO: 文件大小做限制 -->
                <div class="el-upload__tip">
                  <el-text class="mx-1" type="info">
                    仅允许上传一张 500kb .jpg/.png 格式图片
                  </el-text>
                </div>
              </template>
              <el-button type="success">选择图片</el-button>
            </el-upload>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="addDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="submitAddmerchantForm"
              >添加</el-button
            >
          </div>
        </template>
      </el-dialog>
    </div>
    <el-text
      v-if="dialogVisible === false"
      type="info"
      style="
        display: block;
        text-align: center;
        font-size: 24px;
        margin-top: 20px;
      "
    >
      如果您提交了商家信息，请耐心等待管理员审核...
    </el-text>
  </div>
</template>

<style scoped>
.merchant-page {
  padding: 20px;
  background-color: #f5f5f5;
}

.page-card {
  padding: 20px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.header h2 {
  margin: 0;
}

.el-table {
  background-color: #fff;
  border-radius: 8px;
  overflow: hidden;
}
</style>
